package com.xinsoft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.entity.dto.SysLevelPriceRefDTO;
import com.xinsoft.entity.dto.SysLevelPriceRefParam;
import com.xinsoft.entity.dto.SysMaterialImportDTO;
import com.xinsoft.entity.po.SysClientLevel;
import com.xinsoft.entity.po.SysLevelPriceRef;
import com.xinsoft.entity.po.SysMaterial;
import com.xinsoft.service.SysClientLevelService;
import com.xinsoft.service.SysLevelPriceRefService;
import com.xinsoft.mapper.SysLevelPriceRefMapper;
import com.xinsoft.service.SysMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ZYM
 * @description 针对表【sys_level_price_ref(等级价格)】的数据库操作Service实现
 * @createDate 2023-07-25 13:23:50
 */
@Slf4j
@Service
public class SysLevelPriceRefServiceImpl extends ServiceImpl<SysLevelPriceRefMapper, SysLevelPriceRef>
        implements SysLevelPriceRefService {
    @Autowired
    private SysClientLevelService clientLevelService;
    @Autowired
    private SysMaterialService materialService;

    @Override
    public IPage<Map<String, Object>> findPageListByParam(SysLevelPriceRefParam param) {
        Page<Map<String, Object>> page = new Page<>(param.getCurrentPage(), param.getPageSize());

        String sqlFragment = baseMapper.getSqlFragment();
        int lastIndex = sqlFragment.lastIndexOf(",");
        IPage<Map<String, Object>> pageList = baseMapper.findPageListByParam(page, param, sqlFragment.substring(0, lastIndex));

        return pageList;
    }


    @Override
    public void batchUpdatePrice(SysLevelPriceRefDTO sysLevelPriceRefDTO) {
        if (sysLevelPriceRefDTO.getAll().equals(0) && CollectionUtil.isEmpty(sysLevelPriceRefDTO.getMaterialIdList())) {
            throw new BDException("请选择物料");
        }
        if (sysLevelPriceRefDTO.getAll().equals(1)){    //全部修改
            List<SysMaterial> materialList = materialService.list();
            sysLevelPriceRefDTO.setMaterialIdList(materialList.stream().map(SysMaterial::getId).collect(Collectors.toList()));
        }

        List<SysLevelPriceRef> existRefList = this.list(Wrappers.lambdaQuery(SysLevelPriceRef.class)
                .eq(SysLevelPriceRef::getLevelId, sysLevelPriceRefDTO.getFirstLevelId())
                .in(SysLevelPriceRef::getMaterialId, sysLevelPriceRefDTO.getMaterialIdList()));
        List<Integer> existMaterialList = existRefList.stream().map(SysLevelPriceRef::getMaterialId).collect(Collectors.toList());

        // 保存不存在的物料等级价格数据
        List<Integer> noExistMaterialList = sysLevelPriceRefDTO.getMaterialIdList().stream().filter(id -> !existMaterialList.contains(id)).collect(Collectors.toList());
        List<SysLevelPriceRef> noExistRefList = new ArrayList<>();
        noExistMaterialList.forEach(materialId -> {
            SysLevelPriceRef ref = new SysLevelPriceRef();
            ref.setLevelId(sysLevelPriceRefDTO.getFirstLevelId());
            ref.setMaterialId(materialId);
            noExistRefList.add(ref);
        });
        this.saveBatch(noExistRefList);

        // 更新等级价格
        String firstOperator = sysLevelPriceRefDTO.getFirstOperator();
        String secondOperator = sysLevelPriceRefDTO.getSecondOperator();
        String str = firstOperator + sysLevelPriceRefDTO.getConvCoefficient() + secondOperator + sysLevelPriceRefDTO.getPrice();
        sysLevelPriceRefDTO.setExpression(str);
        if (sysLevelPriceRefDTO.getSecondLevelId().equals(-1)) {
            this.baseMapper.batchUpdatePrice1(sysLevelPriceRefDTO);
        } else {
            this.baseMapper.batchUpdatePrice(sysLevelPriceRefDTO);
        }
    }

    @Override
    public List<SysClientLevel> allLevel() {
        return clientLevelService.list();
    }

    @Override
    public void addOrUpdate(List<Map<String, Object>> mapList) {
        List<SysLevelPriceRef> list = new ArrayList<>();
        List<SysClientLevel> levelList = this.allLevel();
        levelList.forEach(lv -> {
            mapList.forEach(map -> {
                if (map.containsKey(lv.getId().toString())) {
                    SysLevelPriceRef ref = new SysLevelPriceRef();
                    ref.setMaterialId((Integer) map.get("materialId"));
                    ref.setLevelId(lv.getId());
                    ref.setSalePrice(new BigDecimal(map.get(lv.getId().toString()).toString()));
                    list.add(ref);
                }
            });

        });
        List<Integer> levelIds = list.stream().map(SysLevelPriceRef::getLevelId).collect(Collectors.toList());
        List<Integer> materialIds = list.stream().map(SysLevelPriceRef::getMaterialId).collect(Collectors.toList());
        List<SysLevelPriceRef> existList = this.list(Wrappers.lambdaQuery(SysLevelPriceRef.class)
                .in(SysLevelPriceRef::getLevelId, levelIds)
                .in(SysLevelPriceRef::getMaterialId, materialIds));
        List<Integer> existLevelIds = existList.stream().map(SysLevelPriceRef::getLevelId).collect(Collectors.toList());
        List<Integer> existMaterialIds = existList.stream().map(SysLevelPriceRef::getMaterialId).collect(Collectors.toList());
        List<SysLevelPriceRef> existRefList = list.stream().filter(ref -> existLevelIds.contains(ref.getLevelId()) && existMaterialIds.contains(ref.getMaterialId())).collect(Collectors.toList());
        List<SysLevelPriceRef> noExistRefList = list.stream().filter(ref -> !existLevelIds.contains(ref.getLevelId()) && !existMaterialIds.contains(ref.getMaterialId())).collect(Collectors.toList());
        // 更新存在的数据
        existRefList.forEach(ref -> {
            this.update(Wrappers.lambdaUpdate(SysLevelPriceRef.class)
                    .eq(SysLevelPriceRef::getLevelId, ref.getLevelId())
                    .eq(SysLevelPriceRef::getMaterialId, ref.getMaterialId())
                    .set(SysLevelPriceRef::getSalePrice, ref.getSalePrice()));
        });
        // 保存不存在的数据
        this.saveBatch(noExistRefList);
    }

}




